﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace QuiddichWPF
{
    /// <summary>
    /// Logique d'interaction pour ModernButton.xaml
    /// </summary>
    public partial class ModernButton : UserControl, ICommandSource
    {
        public static readonly DependencyProperty CommandProperty =
            DependencyProperty.Register("Command", typeof(ICommand), typeof(ModernButton), new PropertyMetadata((ICommand)null, new PropertyChangedCallback(CommandChanged)));

        public static readonly DependencyProperty CommandParameterProperty =
            DependencyProperty.Register("CommandParameter", typeof(object), typeof(ModernButton), new PropertyMetadata(null));

        public static readonly DependencyProperty TextColorProperty =
            DependencyProperty.Register(
                "TextColor", typeof(Brush),
                typeof(ModernButton), new PropertyMetadata(Brushes.White)
            );

        public static readonly new DependencyProperty BackgroundProperty =
            DependencyProperty.Register(
                "Background", typeof(Brush),
                typeof(ModernButton), new PropertyMetadata(Brushes.Black)
           );

        public static readonly RoutedEvent MouseClickEvent = EventManager.RegisterRoutedEvent(
        "MouseClick", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(ModernButton));

        public ICommand Command
        {
            get
            {
                return (ICommand)GetValue(CommandProperty);
            }
            set
            {
                SetValue(CommandProperty, value);
            }
        }

        private static void CommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ModernButton b = (ModernButton)d;
            b.HookUpCommand((ICommand)e.OldValue, (ICommand)e.NewValue);
        }

        private void HookUpCommand(ICommand oldCommand, ICommand newCommand)
        {
            if(oldCommand != null)
            {
                RemoveCommand(oldCommand);
            }

            AddCommand(newCommand);
        }

        private void RemoveCommand(ICommand oldCommand)
        {
            EventHandler handler = CanExecuteChanged;

            oldCommand.CanExecuteChanged -= handler;
        }

        private void AddCommand(ICommand newCommand)
        {
            EventHandler handler = new EventHandler(CanExecuteChanged);

            if (newCommand != null)
                newCommand.CanExecuteChanged += handler;
        }

        private void CanExecuteChanged(object sender, EventArgs e)
        {
            if(this.Command != null)
            {
                RoutedCommand command = this.Command as RoutedCommand;

                if(command != null)
                {
                    if(command.CanExecute(CommandParameter, CommandTarget))
                    {
                        this.IsEnabled = true;
                    }
                    else
                    {
                        this.IsEnabled = false;
                    }
                }
                //If not routed command
                else
                {
                    if(Command.CanExecute(CommandParameter))
                    {
                        this.IsEnabled = true;
                    }
                    else
                    {
                        this.IsEnabled = false;
                    }
                }
            }
        }

        protected override void OnMouseDown(MouseButtonEventArgs e)
        {
            base.OnMouseDown(e);

            Focus();

            if(Command != null)
            {
                RoutedCommand command = Command as RoutedCommand;

                if(command !=null)
                {
                    command.Execute(CommandParameter, CommandTarget);
                }
                else
                {
                    Command.Execute(CommandParameter);
                }
            }
        }

        public event RoutedEventHandler MouseClick
        {
            add
            {
                AddHandler(MouseClickEvent, value);
            }
            remove
            {
                RemoveHandler(MouseClickEvent, value);
            }
        }

        protected void OnMouseClick()
        {
            RoutedEventArgs args = new RoutedEventArgs(ModernButton.MouseClickEvent);
            RaiseEvent(args);
        }

        public new Brush Background
        {
            get
            {
                return (Brush)GetValue(BackgroundProperty);
            }
            set
            {
                SetValue(BackgroundProperty, value);
            }
        }

        public String Title
        {
            get 
            {
                return text.Text;
            }
            set 
            {
                text.Text = value;
            }
        }

        public Brush TextColor
        {
            get
            {
                return (Brush)GetValue(TextColorProperty);
            }
            set
            {
                SetValue(TextColorProperty, value);
            }
        }

        public ModernButton()
        {
            InitializeComponent();

            MouseDown += ModernButton_MouseDown;
        }

        void ModernButton_MouseDown(object sender, MouseButtonEventArgs e)
        {
            OnMouseClick();
            e.Handled = true;
        }

        public object CommandParameter
        {
            get
            {
                return GetValue(CommandParameterProperty);
            }
            set
            {
                SetValue(CommandParameterProperty, value);
            }
        }

        public IInputElement CommandTarget
        {
            get;
            set;
        }
    }
}
